package cn.livingCloud.service.impl;

import cn.livingCloud.context.VelocityFactory;
import cn.livingCloud.entity.core.Case;
import cn.livingCloud.entity.core.CaseStatus;
import cn.livingCloud.entity.core.Employee;
import cn.livingCloud.entity.system.Setting;
import cn.livingCloud.entity.user.Member;
import cn.livingCloud.repository.MemberMapper;
import cn.livingCloud.repository.SettingMapper;
import cn.livingCloud.service.TemplateInfo;
import cn.livingCloud.service.WxTemplateMsgService;
import cn.livingCloud.wechat.template.Templates;
import org.apache.commons.lang.StringUtils;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

/**
 * 发送微信模板消息
 * Created by 唐旭 on 2016/6/30.
 */
@Service
public class WxTemplateMsgServiceImpl implements WxTemplateMsgService {
    private static final Logger LOG = LoggerFactory.getLogger(WxTemplateMsgServiceImpl.class);

    @Autowired
    private SettingMapper settingMapper;
    @Autowired
    private MemberMapper memberMapper;

    @Override
    public void sendTemplate(final TemplateInfo info) {
        if (info == null || StringUtils.isEmpty(info.getTemplateId())) {
            return;
        }
        final Setting setting = settingMapper.findSetting();
        if (setting == null) {
            return;
        }
        //异步线程通知
        new Thread(new Runnable() {
            @Override
            public void run() {
                VelocityEngine engine = VelocityFactory.getEngine();
                VelocityContext context = new VelocityContext();
                StringWriter writer = new StringWriter();
                context.put("data", info.getData());
                context.put("templateId", info.getTemplateId());
                context.put("openid", info.getOpenid());
                context.put("url", info.getUrl());

                engine.evaluate(context, writer, "", info.getTemplateContent());
                String jsonResult = writer.toString();
                LOG.debug("===================发送模板消息=========================");
                LOG.debug("JsonResult:" + jsonResult);
                String sendResult = new Templates().send(setting.getAppid(), setting.getSecret(), jsonResult);
                LOG.debug("发送结果:" + sendResult);
                LOG.debug("===================发送模板消息完成========================");
            }
        }).start();
    }

    /**
     * 发送分派案件模板消息
     *
     * @param aCase 案件
     */
    @Override
    public void sendAssignmentMsg(final Case aCase) {
        ArrayList<TemplateInfo> caseNotifyMsg = createCaseNotifyMsg(aCase, "您有一个新分派的案件,点击查看详情");
        for (TemplateInfo info : caseNotifyMsg) {
            this.sendTemplate(info);
        }
    }

    /**
     * 发送上报案件模板消息
     *
     * @param aCase   案件
     * @param content 上报原因
     */
    @Override
    public void sendReportMsg(final Case aCase, String content) {
        ArrayList<TemplateInfo> caseNotifyMsg = createCaseNotifyMsg(aCase, "您有一个新上报的案件,上报原因:[" + content + "],点击查看详情");
        for (TemplateInfo info : caseNotifyMsg) {
            this.sendTemplate(info);
        }
    }

    /**
     * 向举报者发送 案件作废模板消息
     *
     * @param aCase   案件
     * @param content 作废原因
     */
    @Override
    public void sendCancelMsg(Case aCase, String content) {
        TemplateInfo memberMsg = createMemberMsg(aCase, "您举报的案件已作废,作废原因:[" + content + "],点击查看详情");
        if (memberMsg != null) {
            this.sendTemplate(memberMsg);
        }
    }

    /**
     * 发送案件已完成 模板消息
     *
     * @param aCase 案件
     */
    @Override
    public void sendFinishMsg(Case aCase) {
        TemplateInfo memberMsg = createMemberMsg(aCase, "您举报的案件已完成,点击查看详情");
        if (memberMsg != null) {
            this.sendTemplate(memberMsg);
        }
    }

    @Override
    public void sendPendingMsg(Case aCase, String content) {
        String msg = "";
        CaseStatus status = aCase.getStatus();
        if (status.isFinish()) {
            msg = "案件审核已完成,点击查看详情";
        }
        if (status.isNoHandle()) {
            msg = "案件被驳回,驳回原因:[" + content + "],点击查看详情";
        }
        if (status.isLock()) {
            msg = "案件被驳回多次,已被锁定,点击查看案件";
        }
        ArrayList<TemplateInfo> caseNotifyMsg = createCaseNotifyMsg(aCase, msg);
        for (TemplateInfo info : caseNotifyMsg) {
            this.sendTemplate(info);
        }
    }

    private ArrayList<TemplateInfo> createCaseNotifyMsg(final Case aCase, final Object data) {
        ArrayList<TemplateInfo> infos = new ArrayList<>();
        if (aCase == null || StringUtils.isEmpty(aCase.getOwnerId())) {
            return infos;
        }
        final Setting setting = settingMapper.findSetting();
        if (setting == null) {
            return infos;
        }
        List<Employee> ownerList = aCase.getOwnerList();
        for (final Employee employee : ownerList) {
            List<Member> memberList = memberMapper.findMemberByEmployeeUuid(employee.getUuid());
            for (final Member member : memberList) {
                TemplateInfo info = getTemplateInfo(aCase, data, setting, member);
                infos.add(info);
            }
        }
        return infos;
    }

    /**
     * 创建针对群众的案件模板消息推送
     *
     * @param aCase 案件
     * @param data  数据
     * @return 案件模板详情
     */
    private TemplateInfo createMemberMsg(final Case aCase, final Object data) {
        if (aCase == null || StringUtils.isEmpty(aCase.getOwnerId())) {
            return null;
        }
        final Setting setting = settingMapper.findSetting();
        if (setting == null) {
            return null;
        }

        return getTemplateInfo(aCase, data, setting, aCase.getMember());
    }

    private TemplateInfo getTemplateInfo(final Case aCase, final Object data, final Setting setting, final Member member) {
        return new TemplateInfo() {
            @Override
            public String getTemplateId() {
                return setting.getCaseNotifyId();
            }

            @Override
            public String getOpenid() {
                return member.getOpenid();
            }

            @Override
            public String getUrl() {
                return aCase.getCaseInfoUrl();
            }

            @Override
            public Object getData() {
                return data;
            }

            @Override
            public String getTemplateContent() {
                return setting.getCaseNotifyContent();
            }
        };
    }

}
